package jmine.tec.subscription;

import java.util.Collection;
import java.util.Map;

import jmine.tec.subscription.impl.SubscriptionManagerImplementor;

/**
 * Um {@link Publisher} eh um fornecedor de informacoes. Os publishers ficam responsaveis por gerarem e renovarem as informacoes. Os
 * publishers nao devem fazer cache das publicacoes para que o mecanismo de replicacao funcione
 * 
 * @param <P> o tipo concreto da publication
 * @author takeshi
 */
public interface Publisher<P extends Publication> {

    /**
     * Devolve uma string de identificacao unica.
     * 
     * @return String
     */
    String identification();

    /**
     * @return {@link Class} of P
     */
    Class<P> publicationType();

    /**
     * Devolve a ultima publicacao disponivel para o criterio passado. Este metodo nao precisa forcar a atualizacao da informacao, mas pode
     * gerar a informacao se nenhuma estiver disponivel. Este metodo nao pode devolver <code>null</code>
     * 
     * @param settings {@link SubscriptionSettings}
     * @return Publication
     */
    P newPublication(SubscriptionSettings settings);

    /**
     * Cria uma nova {@link SubscriptionSettings} dados os criterios passados. Idealmente, os {@link Publisher}'s tem como obrigacao
     * 'filtrar' o mapa passado com os criterios requeridos.
     * 
     * @param map o mapa com criterios
     * @return {@link SubscriptionSettings}
     */
    SubscriptionSettings newSubscriptionSettings(Map<String, Object> map);

    /**
     * Devolve a especificacao deste publisher, ou seja, quais parâmetros são necessários para uma assinatura
     * 
     * @return {@link String}
     */
    Map<String, Class<?>> subscriptionSettingsParameters();

    /**
     * Forca a renovacao de um conjunto de {@link SubscriptionSettings}. O publisher deve fazer o possivel para buscar as informacoes mais
     * atualizadas para as publicacoes, embora nao seja um requisito a ida ao banco de dados.
     * 
     * @param settings {@link Collection} de {@link SubscriptionSettings}
     * @return {@link Map} onde as chaves sao as {@link SubscriptionSettings} e os valores sao as {@link Publication}
     */
    Map<SubscriptionSettings, Publication> renewPublications(Collection<? extends SubscriptionSettings> settings);

    /**
     * 'instala' um {@link SubscriptionManagerImplementor} neste publisher.
     * 
     * @param sm {@link SubscriptionManagerImplementor}
     */
    void setSubscriptionManager(SubscriptionManagerImplementor sm);

    /**
     * @param settings the {@link SubscriptionSettings}
     */
    void evict(SubscriptionSettings settings);

}
